﻿using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
//using System.ServiceModel;
//using System.ServiceModel.Web;



namespace WebApplication1
{
    /// <summary>
    /// 使用aspx方式实现
    /// </summary>
    public partial class WXWebForm : System.Web.UI.Page
    {
        //"在微信公众测试号后台写的那个Token";
        const string _token = "duanshaoyan";
        //"你自己微信公众测试号的appID";
        private const string _myOpenid = "wx280555fd8890b0f0";
        string postStr = "";

        protected void Page_Load(object sender, EventArgs e)
        {
            //************** 验证成为开发者的时候将此代码注释 ***********//
            //对微信的信息进行处理和应用
            //WXOpera();


            //***********验证成为开发者之后将此代码注释 * ************//
            string httpmethod = Request.HttpMethod.ToLower();
            if (httpmethod == "post")
            {
                //第一次验证的时候开启
                FirstValid();
            }
            else
            {
                Valid();  //如果不是post请求就去做开发者验证
            }
        }

        #region 成为开发者

        /// <summary>
        /// 验证成为开发者
        /// </summary>
        private void Valid()
        {
            string echoStr = Request.QueryString["echoStr"].ToString();
            if (CheckSignature())
            {
                if (!string.IsNullOrEmpty(echoStr))
                {
                    Response.Write(echoStr);
                    Response.End();
                }
            }
        }

        /// <summary>
        /// 验证微信签名
        /// </summary>
        /// * 将token、timestamp、nonce三个参数进行字典序排序
        /// * 将三个参数字符串拼接成一个字符串进行sha1加密
        /// * 开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。
        /// <returns></returns>
        private bool CheckSignature()
        {
            string signature = Request.QueryString["signature"].ToString();
            string timestamp = Request.QueryString["timestamp"].ToString();
            string nonce = Request.QueryString["nonce"].ToString();
            string[] ArrTmp = { _token, timestamp, nonce };
            Array.Sort(ArrTmp);     //字典排序
            string tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
            tmpStr = tmpStr.ToLower();
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 第一次验证配置
        /// </summary>
        private void FirstValid()
        {
            Stream s = System.Web.HttpContext.Current.Request.InputStream;
            byte[] b = new byte[s.Length];
            s.Read(b, 0, (int)s.Length);
            postStr = Encoding.UTF8.GetString(b);
            if (!string.IsNullOrEmpty(postStr))
            {
                ResponseMsg(postStr);
            }
        }

        /// <summary>
        /// 返回信息结果(微信信息返回)
        /// </summary>
        /// <param name="weixinXML"></param>
        private void ResponseMsg(string weixinXML)
        {
            //回复消息的部分:你的代码写在这里
            Response.Write(weixinXML);
            Response.End();
        }

        #endregion

        #region Click事件的处理,如公众号被订阅时自动回复等

        /// <summary>
        /// 微信操作
        /// </summary>
        private void WXOpera()
        {
            wxmessage wx = GetWxMessage();
            string res = "";
            if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "subscribe")
            {
                //刚关注时的时间，用于欢迎词
                string content = "";
                content = "您好，欢迎关注Cloud家公众号";
                res = sendTextMessage(wx, content);

                HttpContext.Current.Response.Write(res);
                HttpContext.Current.Response.End();
            }
            else if (!string.IsNullOrEmpty(wx.EventName) && wx.EventName.Trim() == "CLICK")
            {
                string key = wx.EventKey;
                switch (key)
                {
                    case "V1001_TODAY_MUSIC":
                        res = TodayMusic(wx);
                        HttpContext.Current.Response.Write(res);
                        HttpContext.Current.Response.End();
                        break;
                }
            }
        }
        /// <summary>
        /// 从请求中获取和设置微信类中的信息
        /// </summary>
        /// <returns></returns>
        private wxmessage GetWxMessage()
        {
            wxmessage wx = new wxmessage();
            StreamReader str = new StreamReader(Request.InputStream, Encoding.UTF8);
            XmlDocument xml = new XmlDocument();
            xml.Load(str);
            str.Close();
            str.Dispose();
            wx.ToUserName = xml.SelectSingleNode("xml").SelectSingleNode("ToUserName").InnerText;
            wx.FromUserName = xml.SelectSingleNode("xml").SelectSingleNode("FromUserName").InnerText;
            wx.MsgType = xml.SelectSingleNode("xml").SelectSingleNode("MsgType").InnerText;
            if (wx.MsgType.Trim() == "text")
            {
                wx.Content = xml.SelectSingleNode("xml").SelectSingleNode("Content").InnerText;
            }
            if (wx.MsgType.Trim() == "event")
            {
                wx.EventName = xml.SelectSingleNode("xml").SelectSingleNode("Event").InnerText;
                wx.EventKey = xml.SelectSingleNode("xml").SelectSingleNode("EventKey").InnerText;
            }
            return wx;
        }

        /// <summary>  
        /// 发送文字消息  
        /// </summary>  
        /// <param name="wx" />获取的收发者信息  
        /// <param name="content" />内容  
        /// <returns></returns>  
        private string sendTextMessage(wxmessage wx, string content)
        {
            string res = string.Format(Message_Text,
                wx.FromUserName, wx.ToUserName, DateTime.Now.Ticks, content);
            return res;
        }

        /// <summary>
        /// 加载今日歌曲
        /// </summary>
        /// <param name="wx"></param>
        /// <returns></returns>
        private string TodayMusic(wxmessage wx)
        {
            //获取推送的今日歌曲
            return sendPicTextMessage(wx, "今日歌曲推荐", "今天点击率最高，最新的歌曲！",
                "http://musicdata.baidu.com/data2/pic/a5c79cf978eb5302edca415cabf744f1/260983581/260983581.jpg",
                "https://www.baidu.com/");

        }

        /// <summary>
        /// 发送图文消息
        /// </summary>
        /// <param name="_mode">微信发送用户信息包</param>
        /// <param name="title">标题</param>
        /// <param name="description">内容</param>
        /// <param name="picurl">图片地址</param>
        /// <param name="url">跳转地址</param>
        /// <returns></returns>
        private string sendPicTextMessage(wxmessage _mode, string title, string description, string picurl, string url)
        {
            string res = string.Format(Message_PicText,
                _mode.FromUserName, _mode.ToUserName, DateTime.Now, title, description, picurl, url);
            return res;
        }



        /// <summary>
        /// 图文消息
        /// </summary>
        private static string Message_PicText
        {
            get
            {
                return @"<xml>
                                <ToUserName><![CDATA[{0}]]></ToUserName>
                                <FromUserName><![CDATA[{1}]]></FromUserName>
                                <CreateTime>{2}</CreateTime>
                                <MsgType><![CDATA[news]]></MsgType>
                                <ArticleCount>1</ArticleCount>
                                <Articles>
                                <item>
                                <Title><![CDATA[{3}]]></Title> 
                                <Description><![CDATA[{4}]]></Description>
                                <PicUrl><![CDATA[{5}]]></PicUrl>
                                <Url><![CDATA[{6}]]></Url>
                                </item>
                                </Articles>
                        </xml>";
            }
        }

        /// <summary>
        /// 普通文本消息
        /// </summary>
        private static string Message_Text
        {
            get
            {
                return @"<xml>
                            <ToUserName><![CDATA[{0}]]></ToUserName>
                            <FromUserName><![CDATA[{1}]]></FromUserName>
                            <CreateTime>{2}</CreateTime>
                            <MsgType><![CDATA[text]]></MsgType>
                            <Content><![CDATA[{3}]]></Content>
                            </xml>";
            }
        }

        #endregion



    }
}